<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, nextTick, reactive } from 'vue'
import type { FieldInstance } from 'vant'

defineProps<{
  iBgColor?: string
  autoHandleKeyboard?: boolean
}>()

const field = ref<FieldInstance | null>(null)
let footer: HTMLElement | null = null

let baselineHeight = 0
let lastIsShow: boolean | null = null
let resizeTimer: number | null = null
let pollTimer: number | null = null
let pollCount = 0
const POLL_MAX = 30 // 最多轮询 30 次，约 3 秒

// 添加设备状态和屏幕方向检测
const deviceState = reactive({
  isPC: false,
  isLandscape: false
})

// 检测是否为PC设备
function isPCDevice() {
  const userAgent = navigator.userAgent
  return !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent)
}

// 检测屏幕方向
function detectOrientation() {
  const isLandscape = window.innerWidth > window.innerHeight
  deviceState.isLandscape = isLandscape
  return isLandscape
}

function onKeyboardChange(isShow: boolean, diff = 0) {
  if (!footer) return
  if (lastIsShow === isShow) return
  lastIsShow = isShow

  // 只有在非PC且非横屏状态下才执行按钮隐藏操作
  if (deviceState.isPC || deviceState.isLandscape) {
    footer.style.bottom = '0'
    footer.style.transition = 'bottom 0.3s ease'
    footer.style.transform = ''
    return
  }

  if (isShow) {
    // 往下移，负值，让按钮跑出视口底部
    footer.style.bottom = `-${diff}px`
    footer.style.transition = 'bottom 0.3s ease'
    footer.style.transform = ''
  } else {
    footer.style.bottom = '0'
    footer.style.transition = 'bottom 0.3s ease'
    footer.style.transform = ''
  }
}

function detectKeyboard() {
  const vh = window.visualViewport?.height || window.innerHeight
  const diff = baselineHeight - vh
  const isShow = diff > 80
  onKeyboardChange(isShow, diff > 0 ? diff : 0)
}

onMounted(() => {
  footer = document.querySelector('.gr-button')

  // 初始化设备状态
  deviceState.isPC = isPCDevice()
  deviceState.isLandscape = detectOrientation()

  nextTick(() => {
    baselineHeight = window.visualViewport?.height || window.innerHeight
  })

  const resizeHandler = () => {
    if (resizeTimer) clearTimeout(resizeTimer)
    resizeTimer = window.setTimeout(() => {
      const vh = window.visualViewport?.height || window.innerHeight
      if (vh > baselineHeight) baselineHeight = vh
      // 更新屏幕方向
      detectOrientation()
      detectKeyboard()
    }, 80)
  }

  if (window.visualViewport) {
    window.visualViewport.addEventListener('resize', resizeHandler)
  } else {
    window.addEventListener('resize', resizeHandler)
  }

  const focusHandler = () => {
    startPolling()
    onKeyboardChange(true, 300) // 300 作为初始偏移，避免闪动
  }
  const blurHandler = () => {
    stopPolling()
    setTimeout(() => onKeyboardChange(false), 80)
  }

  document.addEventListener('focusin', (e) => {
    if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) {
      focusHandler()
    }
  })
  document.addEventListener('focusout', (e) => {
    if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) {
      blurHandler()
    }
  })

  function startPolling() {
    if (pollTimer) return
    pollCount = 0
    pollTimer = window.setInterval(() => {
      pollCount++
      const vh = window.visualViewport?.height || window.innerHeight
      if (vh > baselineHeight) baselineHeight = vh
      detectKeyboard()
      if (pollCount >= POLL_MAX) stopPolling()
    }, 100)
  }
  function stopPolling() {
    if (pollTimer) {
      clearInterval(pollTimer)
      pollTimer = null
    }
  }

  onBeforeUnmount(() => {
    if (window.visualViewport) {
      window.visualViewport.removeEventListener('resize', resizeHandler)
    } else {
      window.removeEventListener('resize', resizeHandler)
    }
    document.removeEventListener('focusin', focusHandler)
    document.removeEventListener('focusout', blurHandler)
    stopPolling()
  })
})
</script>

<template>
  <van-field ref="field" class="rounded-[5px]" :style="{ background: iBgColor }">
    <template v-for="(_, name) in $slots" #[name]="slotData">
      <slot :name="name" v-bind="slotData || {}" />
    </template>
  </van-field>
</template>

<style scoped>
</style>
